package com.yc.jpyy.mobile.service.imp;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;

import com.yc.jpyy.base.bean.RestResponse;
import com.yc.jpyy.base.config.Config;
import com.yc.jpyy.mobile.dao.AdminDao;
import com.yc.jpyy.mobile.dao.BizDao;
import com.yc.jpyy.mobile.service.AdminService;
import com.yc.jpyy.mobile.service.CommonService;

@Service
public class AdminServiceImpl extends CommonService implements AdminService{

	@Autowired
	private AdminDao adminDao;
	
	/*@Autowired
	private MysqlBizDao mysqlBizDao;*/
	
	@Autowired
	private BizDao bizDao;
	
	@Override
	public RestResponse adminLogin(Map<String, Object> paramsMap,
			RestResponse response) throws DataAccessException {
		List<Map<String, Object>> adminmap = adminDao.adminLogin(paramsMap);
		if(null != adminmap && adminmap.size() > 0){		
		    response.setData(adminmap.get(0));	
		}else{
			response.setErrorcode(1);
			response.setMessage("账号或密码错误");
		}
		return response;
	}

	@Override
	public RestResponse getHomePageDatas(String driverId, RestResponse response)
			throws DataAccessException {
		Map<String, Object> map = new HashMap<>();
		//获取教练出勤情况
		Map<String, Object> teachermap = adminDao.getTeacherInfo(driverId);
		if(teachermap != null && teachermap.size() > 0){
			map.put("teacherTotalCount", teachermap.get("total").toString());
			map.put("teacherActualCount", teachermap.get("actualtotal").toString());
		}
		//获取车辆出使用情况
		Map<String, Object> vehiclemap = adminDao.getVehicleInfo(driverId);
		if(teachermap != null && teachermap.size() > 0){
			map.put("vehicleTotalCount", vehiclemap.get("total").toString());
			map.put("vehicleActualCount", vehiclemap.get("actualtotal").toString());
		}
		//获取预约记录
		Map<String, Object> appointmap = adminDao.getAppointInfo(driverId);
		if(teachermap != null && teachermap.size() > 0){
			map.put("appointTotalCount", appointmap.get("total").toString());
			map.put("appointActualCount", appointmap.get("actualcount").toString());
		}
		//获取新增报名人数
		Map<String, Object> premap = adminDao.getPreInfo(driverId);
		if(teachermap != null && teachermap.size() > 0){
			map.put("PreTotalCount", premap.get("total").toString());
		}
		if(map != null && map.size() > 0){
			response.setData(map);
		}else{
			response.setErrorcode(1);
			response.setMessage("未查询到相关数据信息！");
		}
		return response;
	}

	@Override
	public RestResponse getTeacherAttendance(String driverId,String imgUrl,
			RestResponse response) throws DataAccessException {
		List<Map<String, Object>> teachermap = adminDao.getTeacherAttendance(driverId,imgUrl);
		if(null != teachermap && teachermap.size() > 0){		
		    response.setData(teachermap);	
		}else{
			response.setErrorcode(1);
			response.setMessage("没有该驾校的教练出勤情况");
		}
		return response;
	}

	@Override
	public RestResponse getPreUserInfo(String driverId, RestResponse response)
			throws DataAccessException {
		List<Map<String, Object>> premap = adminDao.getPreUserInfo(driverId,Config.getImageAddress());
		if(null != premap && premap.size() > 0){		
		    response.setData(premap);	
		}else{
			response.setErrorcode(1);
			response.setMessage("无该驾校的今日新增报名用户信息");
		}
		return response;
	}

	@Override
	public RestResponse getHistoryCourseRecord(Map<String, Object> paramsMap,
			RestResponse response) throws DataAccessException {
		List<Map<String, Object>> courseMap = adminDao.getCourseRecord(paramsMap);
		if(courseMap != null && !courseMap.isEmpty()){
			courseMap.stream().forEach(map ->{  
				map.put("studentInfo", adminDao.getStudentByCourseId(Optional.ofNullable(map.get("courseId")).orElse("").toString(),
						Optional.ofNullable(map.get("courseType")).orElse("").toString(),Config.getImageAddress()));
				});
			response.setData(courseMap);
		}else{
			response.setErrorcode(0);
			response.setMessage("系统未查询到数据");
		}
		return response;
	}
	
	@Override
	public RestResponse getAppointmentStudents(Map<String, String> paramsMap,
			RestResponse response) throws DataAccessException {
		//查询所有可约学员（预约过同一时间段课程的学员，不可预约）
		List<Map<String, Object>> studentMap = adminDao.getAppointmentStudents(paramsMap);
		if(studentMap != null && !studentMap.isEmpty()){
			//根据课程预约范围，删选学员
			String appRange = Optional.ofNullable(paramsMap.get("appRange")).orElse("").toString();
			if(appRange.equals("1")){//总校任意学院
				studentMap =  studentMap.stream().filter(map -> Optional.ofNullable(map.get("DriveSchoolId"))
						.orElse("").toString().equals(paramsMap.get("driverId"))).collect(Collectors.toList());
			}else if(appRange.equals("2")){//分校人艺学院
				studentMap =  studentMap.stream().filter(map -> Optional.ofNullable(map.get("BranchSchoolId"))
						.orElse("").toString().equals(paramsMap.get("branchSchoolId"))).collect(Collectors.toList());
			}else if(appRange.equals("3")){//分校指定班型
				studentMap =  studentMap.stream().filter(map -> Arrays.asList(paramsMap.get("classIds").toString().split(";")).contains(Optional.ofNullable(map.get("ClassId"))
						.orElse("").toString())).collect(Collectors.toList());
			}else if(appRange.equals("4")){//指定教练
				studentMap = studentMap.stream().filter(map -> 
				Optional.ofNullable(map.get("TeacherId")).orElse("").toString().toString().equals(paramsMap.get("teacherId"))).collect(Collectors.toList());
			}
			if(studentMap != null && !studentMap.isEmpty()){
				response.setData(studentMap);
			}else{
				response.setErrorcode(1);
				response.setMessage("无符合条件学员信息");
			}
		}else{
			response.setErrorcode(1);
			response.setMessage("无可约学员信息");
		}
		return response;
	}

	@Override
	public RestResponse getSlackLearnStudent(Map<String, Object> paramsMap,
			RestResponse response) throws DataAccessException {
		List<Map<String, Object>> adminmap = adminDao.getSlackLearnStudent(paramsMap);
		if(null != adminmap && adminmap.size() > 0){		
		    response.setData(adminmap);	
		}else{
			response.setErrorcode(1);
			response.setMessage("无怠学信息");
		}
		return response;
	}

	@Override
	public RestResponse publishNews(Map<String, Object> paramsMap,
			RestResponse response) throws DataAccessException {
		int i = adminDao.addNews(paramsMap);
		if(i <= 0){		
			response.setErrorcode(1);
			response.setMessage("发布通知信息错误");
		}
		return response;
	}

	@Override
	public RestResponse getNews(Map<String, Object> paramsMap,
			RestResponse response) throws DataAccessException {
		checkParamsMapForPage(paramsMap);
		List<Map<String, Object>> adminmap = adminDao.getNews(paramsMap);
		if(null != adminmap && adminmap.size() > 0){		
		    response.setData(adminmap);	
		}else{
			response.setErrorcode(1);
			response.setMessage("无通知信息");
		}
		return response;
	}

	@Override
	public RestResponse getVehicleListInfo(Map<String, Object> paramsMap,
			RestResponse response) throws DataAccessException {
		List<Map<String, Object>> vehiclemap = adminDao.getVehicleList(paramsMap);
		if(null != vehiclemap && vehiclemap.size() > 0){
			vehiclemap.stream().forEach(map -> {
				map.put("signInfo", adminDao.getVehicleSignInfo(paramsMap.get("driverId").toString(),
						Optional.ofNullable(map.get("vehicleId")).orElse(0).toString()));
			});
		    response.setData(vehiclemap);	
		}else{
			response.setErrorcode(1);
			response.setMessage("无车辆信息");
		}
		return response;
	}

	/*@Override
	public RestResponse getVehicleTraceById(Map<String, Object> paramsMap,
			RestResponse response) throws DataAccessException {
		List<Map<String, Object>> vehiclemap = mysqlBizDao.getVehicleTraceById(paramsMap);
		if(null != vehiclemap && vehiclemap.size() > 0){		
		    response.setData(vehiclemap);	
		}else{
			response.setErrorcode(1);
			response.setMessage("无轨迹信息");
		}
		return response;
	}*/

	@Override
	public RestResponse getTeacherCallList(Map<String, Object> paramsMap,
			RestResponse response) throws DataAccessException {
		List<Map<String, Object>> teachermap = adminDao.getTeacherCallList(paramsMap);
		if(null != teachermap && teachermap.size() > 0){		
		    response.setData(teachermap);	
		}else{
			response.setErrorcode(1);
			response.setMessage("无教练信息");
		}
		return response;
	}
	@Override
	public RestResponse getBlackStudentList(Map<String, Object> paramsMap,
			RestResponse response) throws DataAccessException {
		List<Map<String, Object>> teachermap = adminDao.getBlackStudentList(paramsMap);
		if(null != teachermap && teachermap.size() > 0){		
		    response.setData(teachermap);	
		}else{
			response.setErrorcode(1);
			response.setMessage("无黑名单信息");
		}
		return response;
	}

	@Override
	public RestResponse deleteBlackStudent(String blackId,
			RestResponse response) throws DataAccessException {
		int i= adminDao.deleteBlackStudent(blackId);
		if(i <= 0){
			response.setErrorcode(1);
			response.setMessage("取消失败");
		}
		return response;
	}

	@Override
	public RestResponse courseAppoint(Map<String, Object> paramsMap,
			RestResponse response) throws DataAccessException {
		// 查询该课程的详细信息
		Map<String, Object> appointMap = bizDao.FindappointmentCount(paramsMap);
		if (appointMap != null && !appointMap.isEmpty()) {
			// 获取课程的所属科目
			String subjectId = appointMap.get("courseType").toString();
			// 课程可约学员数
			int appointcount = Integer.parseInt(appointMap
					.get("appointmentCount").toString().isEmpty() ? "0"
					: appointMap.get("appointmentCount").toString());
			// 获取课程日期
			String courseDate = appointMap.get("courseDate").toString();
			// 获取课程时间段
			String courseTimeSlot = appointMap.get("courseTimeSlot").toString();
			String courseNo = Optional.ofNullable(appointMap.get("courseNo")).orElse("").toString();
			String coursePrice = Optional.ofNullable(appointMap.get("coursePrice")).orElse("").toString();
			String courseDiscount = Optional.ofNullable(appointMap.get("courseDiscount")).orElse("").toString();
			paramsMap.put("courseDate", courseDate);
			paramsMap.put("courseTimeSlot", courseTimeSlot);
			paramsMap.put("courseType", subjectId);
			paramsMap.put("courseNo", courseNo);
			paramsMap.put("coursePrice", coursePrice);
			paramsMap.put("courseDiscount", courseDiscount);
			
			String[] studentIds = paramsMap.get("stuId").toString().split(",");
			for(int i = 0; i < studentIds.length; i ++){
				paramsMap.put("stuId",studentIds[i]);
				
				// 判断该课程的支付方式，2余额支付的扣学时，1无需支付的不扣学时
				if (appointMap.get("payPath").toString().equals("2")) {
					// 获取学员可约学时
					Map<String, Object> studytime = bizDao
							.SelectSumSurplusStudyTimes(paramsMap);
					if (studytime != null) {
						// 需要加的学时
						Double times = 0.0;
						// 科一剩余学时
						Double Part1SUMHours = Double.parseDouble(studytime
								.get("Part1SUMHours").toString());
						// 科二剩余学时
						Double Part2SUMHours = Double.parseDouble(studytime
								.get("Part2SUMHours").toString());
						// 科三剩余学时
						Double Part3SUMHours = Double.parseDouble(studytime
								.get("Part3SUMHours").toString());
						// 科四剩余学时
						Double Part4SUMHours = Double.parseDouble(studytime
								.get("Part4SUMHours").toString());
						// 计算课程时长
						Double longTime = Double.parseDouble(appointMap
								.get("intervalTime").toString());
						// 需要加的学时数
						if (appointcount != 0) {
							times = Math.floor(longTime / appointcount);
						}

						if (subjectId.equals("12")) {
							if (Part1SUMHours - times < 0) {
								response.setErrorcode(1);
								response.setMessage("科目一剩余学时不足，无法预约！");
								return response;
							}
						}
						if (subjectId.equals("22")) {
							if (Part2SUMHours - times < 0) {
								response.setErrorcode(1);
								response.setMessage("科目二剩余学时不足，无法预约！");
								return response;
							}
						}
						if (subjectId.equals("32")) {
							if (Part3SUMHours - times < 0) {
								response.setErrorcode(1);
								response.setMessage("科目三剩余学时不足，无法预约！");
								return response;
							}
						}
						if (subjectId.equals("42")) {
							if (Part4SUMHours - times < 0) {
								response.setErrorcode(1);
								response.setMessage("科目四剩余学时不足，无法预约！");
								return response;
							}
						}
						paramsMap.put("courseType", subjectId);
						paramsMap.put("count", times);
						// 更新tb_SurplusStudyTime，剩余学时表
						bizDao.updateSurplusStudyTimes(paramsMap);
					}
				}			
				// 查询是否存在该课程的预约记录
				int num = bizDao.isExisitAppointment(paramsMap);
				if (num > 0) {
					// 如果存在，修改预约记录为已预约（针对取消的情况）
					bizDao.updateCourseAppointment(paramsMap);
				} else {
					// 增加预约记录
					bizDao.CourseAppointment(paramsMap);
				}
				// 给课程表的已预约人数+1
				bizDao.AddReleaseCourseCount(Integer.parseInt(paramsMap
						.get("CourseID").toString()));
			}
			response.setMessage("预约成功！");
		} else {
			response.setErrorcode(1);
			response.setMessage("系统没有查询到该课程！");
		}
		return response;
	}

	@Override
	public RestResponse updatePassword(Map<String, Object> paramsMap,
			RestResponse response) throws DataAccessException {
		String oldPassword = adminDao.getOldPassword(paramsMap);
		if((paramsMap.get("oldPwd").toString()).equals(oldPassword)){
			int i = adminDao.updatePassword(paramsMap);
			if(i > 0){
				response.setErrorcode(0);
				response.setMessage("密码修改完成！");
			}else{
				response.setErrorcode(1);
				response.setMessage("密码修改失败！");
			}
		}else{
			response.setErrorcode(1);
			response.setMessage("原密码填写错误！");
		}
		return response;
	}

	@Override
	public RestResponse getChartDatas(String driverId, RestResponse response)
			throws Exception {
		Map<String,Object> chartDatas = new HashMap<>();
		//学员培训周期分部
		Map<String,Object> studentTrainCycle = adminDao.getStudentTrainCycle(driverId);
		if(studentTrainCycle != null && studentTrainCycle.size() > 0){
			chartDatas.put("studentTrainCycle", studentTrainCycle);
		}
		
		//长期怠学统计分布
		Map<String,Object> longslackStudent = adminDao.getLongslackStudente(driverId);
		if(longslackStudent != null && longslackStudent.size() > 0){
			chartDatas.put("longslackStudent", longslackStudent);
		}
		
		//在校学员培训阶段统计
		Map<String,Object> studentTrainStage = adminDao.getStudentTrainStage(driverId);
		if(studentTrainStage != null && studentTrainStage.size() > 0){
			chartDatas.put("studentTrainStage", studentTrainStage);
		}
		
		//获得最近五年内的年月集合（用于补数据）
		LocalDate now = LocalDate.now();
        LocalDate start = LocalDate.of(now.minusYears(4).getYear(),01,01);
        List<String> monthlist = getMonthBetween(start,now);
        //获得最近一个月的年月日集合
        LocalDate begin = now.minusMonths(1).plusDays(1);
        List<String> daylist = getDayBetween(begin,now);
        
		//学员量变化曲线：（报名）
		List<Map<String,Object>> studentRegisterChange = adminDao.getStudentRegisterChange(driverId);
		//补日期为空的数据
		List<Map<String,Object>> studentRegisterChangeNew = getResultList(monthlist,studentRegisterChange,driverId);	
		if(studentRegisterChangeNew != null && studentRegisterChangeNew.size() >0 ){
			chartDatas.put("studentRegisterChange", studentRegisterChangeNew);
		}
		
		//学员量变化曲线：（结业）
		List<Map<String,Object>> studentGraduateChange = adminDao.getStudentGraduateChange(driverId);
		//补日期为空的数据
		List<Map<String,Object>> studentGraduateChangeNew = getResultList(monthlist,studentGraduateChange,driverId);	
		if(studentGraduateChangeNew != null && studentGraduateChangeNew.size() > 0){
			chartDatas.put("studentGraduateChange", studentGraduateChangeNew);
		}
		
		//学员有效率折线图
		List<Map<String,Object>> studentValidRate = adminDao.getStudentValidRate(driverId);
		//补日期为空的数据
		List<Map<String,Object>> studentValidRateNew = getDayResultList(daylist,studentValidRate,driverId);
		if(studentValidRateNew != null && studentValidRateNew.size() > 0){
			chartDatas.put("studentValidRate", studentValidRateNew);
		}
		//教练车7日均培训时长
		List<Map<String,Object>> teacherSevenTrainAver = adminDao.getTeacherSevenTrainAver(driverId);
		chartDatas.put("teacherSevenTrainAver", teacherSevenTrainAver);
		//教练7日学时有效率统计
		List<Map<String,Object>> teacherSevenValidRate = adminDao.getTeacherSevenValidRate(driverId);
		chartDatas.put("teacherSevenValidRate", teacherSevenValidRate);
		if(chartDatas != null && chartDatas.size() > 0){
			response.setErrorcode(0);
			response.setData(chartDatas);
		}else{
			response.setErrorcode(1);
			response.setMessage("获取数据失败！");
		}
		return response;
	}

	/*@Override
	public RestResponse getVehicleLocation(Map<String, Object> paramsMap,
			RestResponse response) throws Exception {
		List<Map<String,Object>> vehicleLocationMap = mysqlBizDao.getVehicleLocation(paramsMap);
		if(vehicleLocationMap != null && vehicleLocationMap.size() > 0){
			response.setErrorcode(0);
			response.setData(vehicleLocationMap);
		}else{
			response.setErrorcode(1);
			response.setMessage("获取数据失败！");
		}
		return response;
	}*/

	@Override
	public RestResponse getStudentTrainStage(String driverId,
			RestResponse response) throws Exception {
		//在校学员培训阶段统计
		Map<String,Object> studentTrainStage = adminDao.getStudentTrainStage(driverId);
		if(studentTrainStage != null && studentTrainStage.size() > 0){
			response.setErrorcode(0);
			response.setData(studentTrainStage);
		}else{
			response.setErrorcode(1);
			response.setMessage("获取数据失败！");
		}
		return response;
	}

	@Override
	public RestResponse getStudentTrainCycle(String driverId,
			RestResponse response) throws Exception {
		//学员培训周期分部
		Map<String,Object> studentTrainCycle = adminDao.getStudentTrainCycle(driverId);
		if(studentTrainCycle != null && studentTrainCycle.size() > 0){
			response.setErrorcode(0);
			response.setData(studentTrainCycle);
		}else{
			response.setErrorcode(1);
			response.setMessage("获取数据失败！");
		}				
		return response;
	}

	@Override
	public RestResponse getLongslackStudente(String driverId,
			RestResponse response) throws Exception {
		//长期怠学统计分布
		Map<String,Object> longslackStudent = adminDao.getLongslackStudente(driverId);
		if(longslackStudent != null && longslackStudent.size() > 0){
			response.setErrorcode(0);
			response.setData(longslackStudent);
		}else{
			response.setErrorcode(1);
			response.setMessage("获取数据失败！");
		}		
		return response;
	}

	@Override
	public RestResponse getTeacherLeaveInfo(Map<String, Object> paramsMap,
			RestResponse response) throws Exception {
		List<Map<String,Object>> leaveInfo = adminDao.getTeacherLeaveInfo(paramsMap);
		if(leaveInfo != null && leaveInfo.size() > 0){
			response.setErrorcode(0);
			response.setData(leaveInfo);
		}else{
			response.setErrorcode(1);
			response.setMessage("系统无数据！");
		}	
		return response;
	}

	@Override
	public RestResponse getTeacherLeaveDetail(Map<String, Object> paramsMap,
			RestResponse response) throws Exception {
		List<Map<String,Object>> detailInfo = adminDao.getTeacherLeaveDetail(paramsMap);
		//分组
		Map<String,List<Map<String,Object>>> resultMap = detailInfo.stream().collect(
				Collectors.groupingBy(map->map.get("courseDate").toString().substring(0,10)));
		//重组数据（因为根据日期分组后的数据，Key值不固定）
		List<Map<String,Object>> leaveInfo = new ArrayList<Map<String,Object>>();
		for (Entry<String, List<Map<String, Object>>> entry : resultMap.entrySet()) { 
			Map<String,Object> map = new HashMap<>();
			map.put("time", entry.getKey());
			map.put("courses",  entry.getValue());
			leaveInfo.add(map);
		}
		if(leaveInfo != null && leaveInfo.size() > 0){
			response.setErrorcode(0);
			response.setData(leaveInfo);
		}else{
			response.setErrorcode(1);
			response.setMessage("系统无数据！");
		}	
		return response;
	}

	@Override
	public RestResponse deleteCourse(Map<String, Object> paramsMap,
			RestResponse response) throws Exception {
		String[] courseIds = paramsMap.get("courseId").toString().split(",");
		for(int i = 0;i < courseIds.length;i ++){
			paramsMap.put("CourseID", courseIds[i]);
			// 要取消的学时
			Double times = 0.0;
			//查询预约该课程的学员
			List<Map<String,Object>> studentList = adminDao.getStudentList(paramsMap);
			if(studentList != null && studentList.size() > 0){
				//学员ID数组
				List<String> student = studentList.stream().map(map->map.get("stuID").toString()).collect(Collectors.toList());
				String[] studentIds = student.toArray(new String[student.size()]);
				//预约ID数组
				List<String> appoint = studentList.stream().map(map->map.get("appointId").toString()).collect(Collectors.toList());
				String[] appointIds = appoint.toArray(new String[appoint.size()]);
				// 查询该课程的相关信息
				Map<String, Object> appointMap = bizDao.FindappointmentCount(paramsMap);
				if (appointMap != null && !appointMap.isEmpty()) {
					// 课程可预约人数
					int appointcount = Integer.parseInt(appointMap.get(
							"appointmentCount").toString());
					// 计算课程时长
					Double longTime = Double.parseDouble(appointMap.get("intervalTime")
							.toString());
					if (appointcount != 0) {
						times = Math.floor(longTime / appointcount);
					}
					paramsMap.put("appointIds", appointIds);
					// 更改预约状态为已取消
					int j = adminDao.deleteCourseAppointment(paramsMap);
					paramsMap.put("subjectid", appointMap.get("courseType").toString());
					if (j > 0) {
						// 更改课程表的已预约人数学员数量和状态
						paramsMap.put("stuCount", studentIds.length);
						adminDao.delReleaseCourseCount(paramsMap);
						paramsMap.put("count", times);
						// 判断该课程的支付方式，2余额支付的扣学时，1无需支付的不扣学时
						if (appointMap.get("payPath").toString().equals("2")) {
							paramsMap.put("studentIds", studentIds);
							// 更新tb_SurplusStudyTime
							int k = adminDao.delupdateSurplusStudyTimes(paramsMap);
							if(k > 0){
								response.setErrorcode(0);
								response.setMessage("取消预约成功！");
							}else{
								throw new Exception();
							}
						}else{
							response.setErrorcode(0);
							response.setMessage("取消预约成功！");
						}
				    }else{
				    	throw new Exception();
			         }
			  }else{
				  throw new Exception();
			  }
			}else{//没有预约学员，直接取消课程
				int l = adminDao.updateCourseStatus(paramsMap);
				if(l <= 0){
					throw new Exception();
				}
			}
		}
		return response;
	}

	@Override
	public RestResponse updateLeaveStatus(Map<String, Object> paramsMap,
			RestResponse response) throws Exception {
		int count = adminDao.updateLeaveStatus(paramsMap);
		if(count > 0){
			response.setErrorcode(0);
			response.setMessage("审批通过");
		}else{
			response.setErrorcode(1);
			response.setMessage("审批失败！");
		}	
		return response;
	}
}
